// TODO. Somente implementado para P0 e P2 para lpc175x

#include "gpio.h"


/**
 * @brief	Get the pins that has falling edge interrupt enabled
 * @param	p	: The base address of GPIO interrupt block
 * @param	port		: GPIOINT port (gpioPORT0 or GPIOINT_PORT2)
 * @return	Pins that are configured for Falling edge interrupt enabled
 */
//u32 Chip_GPIOINT_GetIntFalling(tGPIOport port)
//{
// tGPIOInt *p = GPIO_INT_BASE;
//	if (port == gpioPORT0) {
//		return p->io0.enf;
//	} else {
//		return p->io2.enf;
//	}
//}

/**
 * @brief	Get pins that has rising edge interrupt enabled
 * @param	p	: The base address of GPIO interrupt block
 * @param	port		: GPIOINT port (gpioPORT0 or GPIOINT_PORT2)
 * @return	Pins that are configured for rising edge interrupt enabled
 */
//u32 Chip_GPIOINT_GetIntRising(tGPIOport port)
//{
// tGPIOInt *p = GPIO_INT_BASE;
//	if (port == gpioPORT0) {
//		return p->io0.enr;
//	} else {
//		return p->io2.enr;
//	}
//}

/**
 * @brief	Get status of the pins for falling edge
 * @param	p	: The base address of GPIO interrupt block
 * @param	port		: GPIOINT port (gpioPORT0 or GPIOINT_PORT2)
 * @return	Pins that has detected falling edge
 */
//u32 Chip_GPIOINT_GetStatusFalling(tGPIOport port)
//{
//	tGPIOInt *p = GPIO_INT_BASE;
//	if (port == gpioPORT0) {
//		return p->io0.statf;
//	} else {
//		return p->io2.statf;
//	}
//}

/**
 * @brief	Get status of the pins for rising edge
 * @param	p	: The base address of GPIO interrupt block
 * @param	port		: GPIOINT port (gpioPORT0 or GPIOINT_PORT2)
 * @return	Pins that has detected rising edge
 */
//u32 Chip_GPIOINT_GetStatusRising(tGPIOport port)
//{
//	tGPIOInt *p = GPIO_INT_BASE;
//	if (port == gpioPORT0) {
//		return p->io0.statr;
//	} else {
//		return p->io2.statr;
//	}
//}

/**
 * @brief	Checks if an interrupt is pending on a given port
 * @param	p	: The base address of GPIO interrupt block
 * @param	port		: GPIOINT port (gpioPORT0 or GPIOINT_PORT2)
 * @return	true if any pin in given port has a pending interrupt
 */
//bool Chip_GPIOINT_IsIntPending(PC_GPIO_PORT_T port)
//{
//	tGPIOInt *p = GPIO_INT_BASE;
//	return ((p->status & (1 << (int)port)) != 0);
//}


// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Coloca um derterminado pino como entrada
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pino as ser ajustado
// Retorna:		Nada
// -------------------------------------------------------------------------------------------------------------------
inline void gpio_SetPinInput(tGPIOport port, u32 pin) {
	tGPIO *p = (tGPIO*)FIO_BASE_ADDR;
	p[port].dir &= ~pin;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Coloca um derterminado pino como saída
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pino as ser ajustado
// Retorna:		Nada
// -------------------------------------------------------------------------------------------------------------------
inline void gpio_SetPinOutput(tGPIOport port, u32 pin) {
	tGPIO *p = (tGPIO*)FIO_BASE_ADDR;
	p[port].dir |= pin;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Liga um pino de uma determinada porta
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pino as ser ajustado
// Retorna:		Nada
// -------------------------------------------------------------------------------------------------------------------
inline void gpio_SetPin(tGPIOport port, u32 pin) {
	tGPIO *p = (tGPIO*)FIO_BASE_ADDR;
	p[port].set = pin;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Desliga um pino de uma determinada porta
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pino as ser ajustado
// Retorna:		Nada
// -------------------------------------------------------------------------------------------------------------------
inline void gpio_ClearPin(tGPIOport port, u32 pin) {
	tGPIO *p = (tGPIO*)FIO_BASE_ADDR;
	p[port].clr = pin;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Habilita a interrupção de borda de descida de um determinado pino
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pinos para configurações
// Retorna:		retorna pdPASS se existe a porta de interrupção, sençao retorna false
// -------------------------------------------------------------------------------------------------------------------
int gpio_SetIntFalling(tGPIOport port, u32 pins) {
	tGPIOInt *p = GPIO_INT_BASE;
	if (port==gpioPORT0) p->io0.enf = pins;
	else if (port==gpioPORT2) p->io2.enf = pins;
	else return pdFALSE;
	return pdPASS;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Habilita a interrupção de borda de subida de um determinado pino
// Parametros:	port: Porta GPIO para configuração do pino
//				pins: Pinos para configurações
// Retorna:		retorna pdPASS se existe a porta de interrupção, sençao retorna false
// -------------------------------------------------------------------------------------------------------------------
int gpio_SetIntRising(tGPIOport port, u32 pins) {
	tGPIOInt *p = GPIO_INT_BASE;
	if (port == gpioPORT0) p->io0.enr = pins;
	else if (port == gpioPORT2) p->io2.enr = pins;
	else return pdFALSE;
	return pdPASS;
}

// -------------------------------------------------------------------------------------------------------------------
// Descrição: 	Limpa a interrupção de subida ou queda de um determinado pino
// Parametros:	port: Porta GPIO para limpeza
//				pins: Pinos para limpar a interrução
// Retorna:		retorna pdPASS se existe a porta de interrupção, sençao retorna false
// -------------------------------------------------------------------------------------------------------------------
int gpio_ClearIntStatus(tGPIOport port, u32 pins) {
	tGPIOInt *p = GPIO_INT_BASE;
	if (port==gpioPORT0) p->io0.clr = pins;
	else if (port==gpioPORT2) p->io2.clr = pins;
	else return pdFALSE;
	return pdPASS;
}
